/**
 * imageService.js
 * 提供医学影像查看器的图像加载、预加载和缓存管理功能
 * 合并了原 imageLoaderService.js 和 imagePreloadService.js 的功能
 */
import cornerstone from 'cornerstone-core';
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader';
import orthancService from '@/services/orthancService';

// 存储已加载的图像，用于缓存管理
const loadedImagesCache = new Set();

// 滚动方向检测的状态
let _lastIndex = null;

/**
 * 配置WADO图像加载器
 * @param {string} authHeader - 认证头信息
 */
export function configureImageLoader(authHeader) {
  // 配置 WADO 图像加载器
  cornerstoneWADOImageLoader.configure({
    beforeSend: (xhr) => {
      // 添加认证信息
      if (authHeader) {
        xhr.setRequestHeader('Authorization', authHeader);
      }
    },
    useWebWorkers: true,
    decodeConfig: {
      convertFloatPixelDataToInt: false,
      use16Bits: true
    }
  });
  
  // 启用 web worker
  const config = {
    maxWebWorkers: navigator.hardwareConcurrency || 4,
    startWebWorkersOnDemand: true,
    webWorkerPath: '/cornerstoneWADOImageLoaderWebWorker.js',
    taskConfiguration: {
      decodeTask: {
        loadCodecsOnStartup: true,
        initializeCodecsOnStartup: true
      }
    }
  };
  
  cornerstoneWADOImageLoader.webWorkerManager.initialize(config);
}

/**
 * 加载单张图像
 * @param {string} instanceId - 实例ID
 * @returns {Promise<Object>} 加载的图像对象
 */
export async function loadImage(instanceId) {
  try {
    // 创建图像ID
    const imageId = `wadouri:/api/instances/${instanceId}/file`;
    
    // 加载并缓存图像
    const image = await cornerstone.loadAndCacheImage(imageId);
    
    // 将图像ID添加到缓存集合
    loadedImagesCache.add(imageId);
    
    return { 
      success: true, 
      image,
      imageId
    };
  } catch (error) {
    console.error('加载图像失败:', error);
    return {
      success: false,
      error: error.message || '图像加载失败',
      imageId: null
    };
  }
}

/**
 * 按照 DICOM 标签对实例进行排序
 * @param {Array} instances - 实例数组
 * @returns {Promise<Array>} 排序后的实例数组
 */
export async function sortInstances(instances) {
  try {
    if (!instances || instances.length === 0) {
      return [];
    }
    
    // 如果只有一个实例，无需排序
    if (instances.length === 1) {
      return instances;
    }
    
    // 收集标签数据
    const instancesWithPosition = [];
    
    for (const instance of instances) {
      try {
        const tags = await orthancService.getInstanceTags(instance);
        
        if (tags && tags.Tags) {
          // 尝试从多个可能的标签中获取位置信息
          let position = null;
          
          // 尝试 ImagePositionPatient 标签
          if (tags.Tags.ImagePositionPatient) {
            position = tags.Tags.ImagePositionPatient;
          }
          // 尝试 SliceLocation 标签
          else if (tags.Tags.SliceLocation) {
            position = tags.Tags.SliceLocation;
          }
          // 尝试 InstanceNumber 标签
          else if (tags.Tags.InstanceNumber) {
            position = tags.Tags.InstanceNumber;
          }
          
          // 处理位置字符串
          if (typeof position === 'string') {
            if (position.includes('\\')) {
              // 如果是 ImagePositionPatient 格式 (x\y\z)
              const parts = position.split('\\');
              // 使用 z 坐标排序
              position = parseFloat(parts[2] || 0);
            } else {
              // 单个数值的情况
              position = parseFloat(position);
            }
          }
          
          // 添加到数组供排序
          instancesWithPosition.push({
            instance,
            position: isNaN(position) ? 0 : position,
            instanceNumber: parseInt(tags.Tags.InstanceNumber || '0', 10)
          });
        } else {
          // 没有标签信息的情况
          instancesWithPosition.push({
            instance,
            position: 0,
            instanceNumber: 0
          });
        }
      } catch (error) {
        console.error(`获取实例 ${instance.ID} 标签失败:`, error);
        // 加入队列，但没有位置信息
        instancesWithPosition.push({
          instance,
          position: 0,
          instanceNumber: 0
        });
      }
    }
    
    // 排序逻辑: 优先按位置排序，如果位置相同则按实例编号排序
    instancesWithPosition.sort((a, b) => {
      // 首先按位置排序
      if (a.position !== b.position) {
        return a.position - b.position;
      }
      // 如果位置相同，按实例编号排序
      return a.instanceNumber - b.instanceNumber;
    });
    
    // 返回排序后的实例数组
    return instancesWithPosition.map(item => item.instance);
  } catch (error) {
    console.error('排序实例失败:', error);
    // 出错时返回原始顺序
    return instances;
  }
}

/**
 * 获取认证头信息
 * @returns {string} 认证头信息
 */
export function getAuthHeader() {
  const username = 'orthanc';
  const password = 'orthanc123';
  return 'Basic ' + btoa(`${username}:${password}`);
}

/**
 * 显示图像
 * @param {Element} element - 用于显示图像的DOM元素
 * @param {Object} image - cornerstone图像对象
 * @param {Object} options - 显示选项
 */
export function displayImage(element, image, options = {}) {
  try {
    cornerstone.displayImage(element, image, options);
    return true;
  } catch (error) {
    console.error('显示图像失败:', error);
    return false;
  }
}

/**
 * 检测滚动方向
 * @param {number} currentIndex - 当前图像索引
 * @returns {number} - 方向值，正数表示向前，负数表示向后
 * @private
 */
function _detectScrollDirection(currentIndex) {
  // 简单的方向检测
  if (_lastIndex === null) {
    _lastIndex = currentIndex;
    return 1; // 默认向前
  }
  
  const direction = currentIndex - _lastIndex;
  _lastIndex = currentIndex;
  return direction;
}

/**
 * 执行相邻图像预加载
 * @param {number} currentIndex - 当前图像索引
 * @param {Array<string>} imageIds - 所有图像ID数组
 * @private
 */
function _performAdjacentPreload(currentIndex, imageIds) {
  if (!imageIds || imageIds.length === 0) return;
  
  // 预测用户可能的浏览方向
  const direction = _detectScrollDirection(currentIndex);
  const preloadCount = 5; // 预加载数量
  
  const imagesToPreload = [];
  
  if (direction >= 0) {
    // 向前预加载
    for (let i = 1; i <= preloadCount; i++) {
      const index = currentIndex + i;
      if (index < imageIds.length) {
        imagesToPreload.push(imageIds[index]);
      }
    }
  } else {
    // 向后预加载
    for (let i = 1; i <= preloadCount; i++) {
      const index = currentIndex - i;
      if (index >= 0) {
        imagesToPreload.push(imageIds[index]);
      }
    }
  }
  
  // 使用低优先级加载
  imagesToPreload.forEach(imageId => {
    cornerstone.loadAndCacheImage(imageId, { priority: -5 });
  });
}

/**
 * 预加载相邻图像
 * @param {number} currentIndex - 当前图像索引
 * @param {Array<string>} imageIds - 所有图像ID数组
 */
export function preloadAdjacentImages(currentIndex, imageIds) {
  // 如果浏览器处于空闲状态，才进行预加载
  if ('requestIdleCallback' in window) {
    window.requestIdleCallback(() => {
      _performAdjacentPreload(currentIndex, imageIds);
    }, { timeout: 1000 });
  } else {
    // 降级处理
    setTimeout(() => {
      _performAdjacentPreload(currentIndex, imageIds);
    }, 100);
  }
}

/**
 * 带进度条的预加载
 * @param {Array<string>} imageIds - 图像ID数组
 * @param {Object} series - 序列对象，用于更新加载进度
 * @returns {Promise<void>}
 */
export function preloadImagesWithProgress(imageIds, series) {
  if (!imageIds || imageIds.length === 0) return;
  
  // 配置并发加载参数
  const concurrentRequests = 4;
  
  // 创建加载队列
  let queue = [...imageIds];
  let activeRequests = 0;
  let completed = 0;
  
  // 处理队列中的下一个图像
  const processNext = () => {
    if (queue.length === 0 && activeRequests === 0) {
      // 所有图像已处理完成
      if (series) {
        series.loading = false;
        series.loadProgress = 100;
      }
      return;
    }
    
    // 如果队列为空或已达到最大并发数，则返回
    if (queue.length === 0 || activeRequests >= concurrentRequests) {
      return;
    }
    
    // 从队列中取出下一个图像ID
    const imageId = queue.shift();
    
    // 如果图像已加载，则处理下一个
    if (loadedImagesCache.has(imageId)) {
      processNext();
      return;
    }
    
    // 增加活动请求计数
    activeRequests++;
    
    // 加载图像
    cornerstone.loadAndCacheImage(imageId)
      .then(() => {
        // 标记为已加载
        loadedImagesCache.add(imageId);
        completed++;
        
        // 更新序列加载进度
        if (series) {
          const progress = Math.min(Math.round((completed / imageIds.length) * 100), 100);
          series.loadProgress = progress;
        }
      })
      .catch(error => {
        console.error(`加载图像 ${imageId} 失败:`, error);
      })
      .finally(() => {
        // 减少活动请求计数
        activeRequests--;
        
        // 处理下一个图像
        processNext();
      });
    
    // 如果还有空闲槽位，继续处理
    processNext();
  };
  
  // 开始处理队列
  for (let i = 0; i < Math.min(concurrentRequests, queue.length); i++) {
    processNext();
  }
}

/**
 * 高性能图像预加载，具有优先级控制
 * @param {Array<string>} imageIds - 图像ID数组，或实例ID数组
 * @param {Object} options - 预加载选项
 * @param {number} options.currentIndex - 当前图像索引
 * @param {Function} options.onProgress - 进度回调
 * @param {number} options.concurrentRequests - 并发请求数量
 * @param {boolean} options.isInstanceIds - 是否为实例ID而非图像ID
 * @returns {Promise<Set>} 已加载图像集合
 */
export function preloadImages(imageIds, options = {}) {
  const { 
    currentIndex = 0, 
    onProgress = () => {}, 
    concurrentRequests = 6,
    isInstanceIds = false
  } = options;
  
  return new Promise((resolve) => {
    // 如果无图像需要预加载，直接返回
    if (!imageIds || imageIds.length === 0) {
      resolve(new Set());
      return;
    }
    
    // 如果传入的是实例ID，转换为图像ID
    const processedImageIds = isInstanceIds 
      ? imageIds.map(id => `wadouri:/api/instances/${id}/file`)
      : imageIds;
    
    // 记录开始时间，用于性能跟踪
    const startTime = performance.now();
    
    // 优先级排序 - 当前图像附近的优先加载
    const prioritizedIds = processedImageIds.map((id, index) => ({
      id,
      priority: Math.abs(index - currentIndex) // 距离当前图像的距离作为优先级
    }))
    .sort((a, b) => a.priority - b.priority) // 按优先级排序
    .map(item => item.id);
    
    // 创建加载队列
    let queue = [...prioritizedIds];
    let activeRequests = 0;
    let completed = 0;
    
    // 处理队列中的下一个图像
    const processNext = () => {
      // 检查是否所有图像已处理完成
      if (queue.length === 0 && activeRequests === 0) {
        const totalTime = performance.now() - startTime;
        console.log(`✅ 所有图像加载完成，总耗时: ${totalTime.toFixed(2)}ms，平均每张: ${(totalTime / processedImageIds.length).toFixed(2)}ms`);
        resolve(loadedImagesCache);
        return;
      }
      
      // 如果队列为空或已达到最大并发数，则返回
      if (queue.length === 0 || activeRequests >= concurrentRequests) {
        return;
      }
      
      // 从队列中取出下一个图像ID
      const imageId = queue.shift();
      
      // 如果图像已加载，则处理下一个
      if (loadedImagesCache.has(imageId)) {
        processNext();
        return;
      }
      
      // 增加活动请求计数
      activeRequests++;
      
      // 加载图像
      cornerstone.loadAndCacheImage(imageId)
        .then(() => {
          // 标记为已加载
          loadedImagesCache.add(imageId);
          completed++;
          
          // 调用进度回调
          onProgress(completed, processedImageIds.length);
          
          // 每加载10张图像打印一次进度
          if (completed % 10 === 0) {
            const percentage = Math.min(Math.round((completed / processedImageIds.length) * 100), 100);
            console.log(`已加载 ${completed}/${processedImageIds.length} 张图像 (${percentage}%)`);
          }
        })
        .catch(error => {
          console.error(`加载图像 ${imageId} 失败:`, error);
        })
        .finally(() => {
          // 减少活动请求计数
          activeRequests--;
          
          // 处理下一个图像
          processNext();
          
          // 同时启动更多的加载任务保持并发性
          for (let i = 0; i < Math.min(concurrentRequests - activeRequests, queue.length); i++) {
            processNext();
          }
        });
    };
    
    // 启动初始的并发加载
    for (let i = 0; i < Math.min(concurrentRequests, queue.length); i++) {
      processNext();
    }
  });
}

/**
 * 清理图像缓存
 * @param {Array<string>} excludeImageIds - 不清理的图像ID列表
 * @returns {number} 已清理的图像数量
 */
export function cleanImageCache(excludeImageIds = []) {
  try {
    const excludeSet = new Set(excludeImageIds);
    const cachedImageIds = Object.keys(cornerstone.imageCache.cachedImages);
    let purgeCount = 0;
    
    // 遍历所有缓存的图像
    cachedImageIds.forEach(imageId => {
      // 如果不在排除列表中，则清理
      if (!excludeSet.has(imageId)) {
        cornerstone.imageCache.purgeCache(imageId);
        purgeCount++;
      }
    });
    
    console.log(`已清理 ${purgeCount} 张缓存图像`);
    return purgeCount;
  } catch (error) {
    console.error('清理图像缓存失败:', error);
    return 0;
  }
}

/**
 * 获取图像缓存信息
 * @returns {Object} 缓存信息统计
 */
export function getCacheStats() {
  try {
    const cachedImages = cornerstone.imageCache.cachedImages;
    const cachedImageIds = Object.keys(cachedImages);
    
    // 计算缓存大小
    let totalSizeInBytes = 0;
    let totalImages = cachedImageIds.length;
    
    cachedImageIds.forEach(imageId => {
      const image = cachedImages[imageId].image;
      if (image && image.sizeInBytes) {
        totalSizeInBytes += image.sizeInBytes;
      }
    });
    
    // 转换为可读的大小
    const totalSizeInMB = (totalSizeInBytes / (1024 * 1024)).toFixed(2);
    
    return {
      totalImages,
      totalSizeInBytes,
      totalSizeInMB,
      cachedImageIds
    };
  } catch (error) {
    console.error('获取缓存统计信息失败:', error);
    return {
      totalImages: 0,
      totalSizeInBytes: 0,
      totalSizeInMB: '0.00',
      cachedImageIds: []
    };
  }
}

export default {
  // 图像加载相关
  configureImageLoader,
  loadImage,
  displayImage,
  getAuthHeader,
  
  // 图像处理相关
  sortInstances,
  
  // 预加载相关
  preloadImages,
  preloadImagesWithProgress,
  preloadAdjacentImages,
  
  // 缓存管理
  cleanImageCache,
  getCacheStats
} 